package com.polaris.live.utils

import android.Manifest
import android.app.Activity
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.os.Build
import android.provider.Settings
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationManagerCompat
import com.blankj.utilcode.util.PermissionUtils
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.enums.PopupAnimation
import com.lxj.xpopup.interfaces.SimpleCallback
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.constant.AppConst
import com.polaris.live.common.util.SystemUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.popup.PushNoticePopup
import com.polaris.live.resp.bean.PromptNoticeBean
import com.polaris.live.widget.PushNoticeView

/**
 * 推送通知工具类
 *
 * @author Created by lucas on 2023/12/11 08:06
 */
object PushNoticeUtils {

    const val CHANNEL_ID_PUSH = "wejoy"

    /**
     * 请求通知
     */
    fun permissionNotice(
        context: Activity,
        agreeBlock: () -> Unit = {},
        refuseBlock: () -> Unit = {},
    ) {
        if (SystemUtils.isSdkInt33()) {
            val beforeShouldShow = shouldShowRequestPermissionRationale(context, Manifest.permission.POST_NOTIFICATIONS)

            val list = listOf(Manifest.permission.POST_NOTIFICATIONS)
            PermissionUtils.permissionGroup(*arrayOf(Manifest.permission.POST_NOTIFICATIONS))
                .callback(object : PermissionUtils.FullCallback {
                    override fun onGranted(granted: MutableList<String>) {
                        if (list.size != granted.size) {
                            refuseBlock()
                        } else {
                            agreeBlock()
                        }
                    }

                    override fun onDenied(
                        deniedForever: MutableList<String>,
                        denied: MutableList<String>,
                    ) {
                        val afterShouldShow =
                            shouldShowRequestPermissionRationale(context, Manifest.permission.POST_NOTIFICATIONS)
                        if (beforeShouldShow || afterShouldShow) {
                            refuseBlock()
                        } else {
                            toNoticeSetting(context)
                        }
                    }
                }).request()
        } else {
            if (hasNoticePermission(context)) {
                agreeBlock()
            } else {
                toNoticeSetting(context)
            }
        }
    }

    // 检查是否应该显示权限请求对话框
    private fun shouldShowRequestPermissionRationale(context: Activity, permission: String): Boolean {
        return if (SystemUtils.isSdkInt23()) {
            ActivityCompat.shouldShowRequestPermissionRationale(context, permission)
        } else {
            false
        }
    }

    /**
     * 跳转到通知设置页面
     */
    private fun toNoticeSetting(context: Context) {
        if (SystemUtils.isSdkInt26()) {
            startToNotificationSetting(context)
        } else {
            PermissionUtils.launchAppDetailsSettings()
        }
    }

    const val REQUEST_CODE_NOTIFICATION = 1091

    /**
     * 跳转到自己的通知设置页面
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private fun startToNotificationSetting(context: Context) {
        if (context !is Activity) {
            return
        }
        try {
            val intent = Intent()
            intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName())
            context.startActivityForResult(intent, REQUEST_CODE_NOTIFICATION)
        } catch (e: Exception) {
            ToastGravity.showGravity("无法打开设置页面，请您去设置页面自行设置")
        }
    }

    /**
     * 是否需要通知权限
     */
    fun needNoticePermission(): Boolean {
        return (isOpened(UserManager.getUser().setting?.liveNotice)
                || isOpened(UserManager.getUser().setting?.chatNotice)
                || isOpened(UserManager.getUser().setting?.callNotice))
    }

    private fun isOpened(switch: Int?): Boolean {
        return switch != AppConst.NO
    }

    /**
     * 是否有推送通知消息权限
     */
    fun hasNoticePermission(context: Context): Boolean {
        if (!isPermissionNotification(context)) {
            return false
        }
        if (SystemUtils.isSdkInt26()) {
            val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
                ?: return false
            val notificationChannel = notificationManager.getNotificationChannel(CHANNEL_ID_PUSH)
                ?: return true
            return notificationChannel.importance != NotificationManager.IMPORTANCE_NONE
        }
        return true
    }

    /**
     * 是否有通知权限
     */
    private fun isPermissionNotification(context: Context): Boolean {
        return NotificationManagerCompat.from(context).areNotificationsEnabled()
    }

    /**
     * 显示通知弹窗
     */
    fun showNotice(context: Context, message: PromptNoticeBean, dismissBlock: () -> Unit): BasePopupView {
        return XPopup.Builder(context)
            .setPopupCallback(object : SimpleCallback() {
                override fun onDismiss(popupView: BasePopupView?) {
                    dismissBlock()
                }
            })
            .hasShadowBg(false)
            .isViewMode(true)
            .isRequestFocus(false)
            .isDestroyOnDismiss(true)
            .dismissOnBackPressed(false)
            .dismissOnTouchOutside(false)
            .isClickThrough(true)
            .isTouchThrough(true)
            .isDestroyOnDismiss(true)
            .popupAnimation(PopupAnimation.TranslateFromTop)
            .asCustom(PushNoticePopup(context, message))
            .show()
    }


    /**
     * 直接添加view通知
     */
    fun showViewNotice(context: Context, message: PromptNoticeBean, dismissBlock: () -> Unit) {
        PushNoticeView(context, message, dismissBlock).show()
    }
}